其他
利用Frida破解黑盒环境的Dex函数抽取壳
看雪论坛作者ID:飞翔的猫咪
题目出自看雪高研班2021年10月份作业第二题:
函数抽取壳导致了被保护的函数始终运行在解释模式下。提供的pixel镜像已经将默认解释器修改成了Switch实现,请分析该Switch解释器,并编写frida hook脚本,能够实现对解释器解释执行的每一条smali指令的跟踪记录。提供的测试apk采用了自解密的函数抽取技术。
分析:
对于题目中的8.0系统,解释器分为Switch实现和Mterp汇编实现的解释器,Switch实现要好分析很多,因此手头上如果有源码的情况下可以强制解释器用Switch来实现。
做这道题目可以开扩脱壳的思路,原来就算没有源码的情况下,用ida分析so也可以找到脱壳点。了解壳的根本原理以及虚拟机执行的原理才是以不变应万变的法则,剩下的就靠创造力去发挥即可。
解答:
var prettyMethodPtr;
var prettyMethod;
function pretty_method(art_method) {
if (!prettyMethodPtr) {
prettyMethodPtr = Module.getExportByName("libart.so", "_ZN3art9ArtMethod12PrettyMethodEb");
prettyMethod = new NativeFunction(prettyMethodPtr, 'pointer', ['pointer', 'pointer', 'bool']);
}
var result = Memory.alloc(0x100);
prettyMethod(ptr(result), art_method, 1);
return result.add(0x8).readPointer().readCString();
}
var in_method = false;
var target_method_name = "com.xgtl.aggregate.activities.MainActivity.a(android.view.View)";
function hookGetThisObject(base) {
var get_this_object_addr = Module.getExportByName("libart.so", "_ZNK3art11ShadowFrame13GetThisObjectEt");
Interceptor.attach(get_this_object_addr, {
onEnter: function (args) {
console.log("pid :" + Process.getCurrentThreadId() + ", lr:" + ptr(this.context.lr).sub(base).add(0xB000));
console.log(hexdump(ptr(this.context.r11), { length: 32 }));
console.log()
}, onLeave: function (retval) {
}
});
}
function hook() {
var libartmodule = Process.getModuleByName("libart.so");
var base = libartmodule.base;
libartmodule.enumerateSymbols().forEach(function (symbol) {
if (symbol.name.indexOf("ExecuteSwitchImpl") != -1 && symbol.name.indexOf("CodeItem") != -1) {
Interceptor.attach(symbol.address, {
onEnter: function (args) {
var instance = ptr(0x43898C).add(base).sub(0xB000).add(0xca9f4).add(480);
instance.writeU8(1);
var shadow_frame = args[3];
var art_method = ptr(shadow_frame).add(Process.pointerSize).readPointer();
this.method_name = pretty_method(art_method);
if (this.method_name.indexOf(target_method_name) != -1) {
console.log("method start : >>>>>>>>>>>" + this.method_name);
hookGetThisObject(base, this.method_name);
in_method = true;
}
if (in_method) {
console.log("method start : >>>>>>>>>>>" + this.method_name);
}
}, onLeave: function (retval) {
if (this.method_name.indexOf(target_method_name) != -1) {
console.log("method end : >>>>>>>>>>>" + this.method_name);
Interceptor.detachAll();
in_method = false;
}
}
});
}
});
}
function main() {
hook();
}
setImmediate(main);
[AOSP on msm8996::com.xgtl.assistant]-> method start : >>>>>>>>>>>void com.xgtl.aggregate.activities.MainActivity.a(android.view.View)
method start : >>>>>>>>>>>void com.xgtl.aggregate.activities.MainActivity.a(android.view.View)
pid :16444, lr:0x206a57
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
c4bce9f8 28 1b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (...............
c4bcea08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
pid :16444, lr:0x203a79
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
c4bcea2e 14 00 5f 18 00 00 71 10 4e df 00 00 28 e0 02 00 .._...q.N...(...
c4bcea3e 02 00 02 00 00 00 00 00 00 00 09 00 00 00 12 01 ................
pid :16444, lr:0x203f87
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
c4bcea34 71 10 4e df 00 00 28 e0 02 00 02 00 02 00 00 00 q.N...(.........
c4bcea44 00 00 00 00 09 00 00 00 12 01 70 20 87 ca 10 00 ..........p ....
pid :16444, lr:0x206a57
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
c4bcea3a 28 e0 02 00 02 00 02 00 00 00 00 00 00 00 09 00 (...............
c4bcea4a 00 00 12 01 70 20 87 ca 10 00 0c 01 71 20 50 ca ....p ......q P.
method start : >>>>>>>>>>>void com.xgtl.aggregate.activities.MainActivity.a(android.view.View)
lr:0x206a57 = goto 1b
lr:0x203a79 = const v0, 0x0000185f
lr:0x203f87 = invoke-static {v0},kind@df4e = invoke-static {v0},Ls/h/e/l/l/H;->i(I)V
lr:0x206a57 = goto e0
lr:0x2046e7 = iget-object v0,v2,field@8188 = Landroid/support/v4/media/MediaBrowserServiceCompat;->mSession:Landroid/support/v4/media/session/MediaSessionCompat$Token;
lr:0x205ccf = const/4 vA, #+B = const/4 v1,#0
lr:0x204c49 = invoke-virtual {v0, v1}, kind@61b5
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatImageView.drawableStateChanged()
lr:0x2064ad = invoke-super {v0}, kind@614c
lr:0x2046e7 = iget-object v0,v1,field@32ae
lr:0x20466d = if-eqz v0,0x0005
lr:0x204c49 = invoke-virtual {v0},kind@4b5b = void android.support.v7.widget.AppCompatBackgroundHelper.applySupportBackgroundTint()
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatBackgroundHelper.applySupportBackgroundTint()
lr:0x2046e7 = iget-object v0,v3,field@3285
lr:0x204c49 = invoke-virtual {v0},kind@5cd5
lr:0x206c21 = move-result-object v0
lr:0x20466d = if-eqz v0,0x0022
lr:0x20c951 = return-void
lr:0x2046e7 = iget-object v0,v1,field@32af
lr:0x20466d = if-eqz v0,0x0005
lr:0x204c49 = invoke-virtual {v0},kind@4bef
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatImageHelper.applySupportImageTint()
lr:0x2046e7 = iget-object v0,v3,field@32ad
lr:0x204c49 = invoke-virtual {v0},kind@6150
lr:0x206c21 = move-result-object v0
lr:0x20466d = if-eqz v0,0x0005
lr:0x203f87 = invoke-static {v0}, kind@4e6e
method start : >>>>>>>>>>>void android.support.v7.widget.DrawableUtils.fixDrawable(android.graphics.drawable.Drawable)
lr:0x203f09 = sget v0, field@0467
lr:0x204023 = const/16 v1, 0x0015
lr:0x204301 = if-ne v0,v1,0x0015
lr:0x20c951 = return-void
lr:0x20466d = if-eqz v0,0x0022
lr:0x206729 = invoke-direct {v3}, kind@4bf8
method start : >>>>>>>>>>>boolean android.support.v7.widget.AppCompatImageHelper.shouldApplyFrameworkTintUsingColorFilter()
lr:0x203f09 = sget v0, field@0467
lr:0x205ccf = const/4 v1,#1
lr:0x205ccf = const/4 v2,#0
lr:0x204023 = const/16 v3, 0x0015
lr:0x204b7b = if-le v0,v3,0x0009
lr:0x2046e7 = iget-object v0,v4,field@32ab
lr:0x20466d = if-eqz v0,0x0003
lr:0x205ccf = const/4 v1,#0
lr:0x20c9f1 = return v1
lr:0x2051d5 = move-result v1
lr:0x20466d = if-eqz v1,0x0009
lr:0x2046e7 = iget-object v1,v3,field@32aa
lr:0x20466d = if-eqz v1,0x000c
lr:0x2046e7 = iget-object v1,v3,field@32ab
lr:0x20466d = if-eqz v1,0x0003
lr:0x20c951 = return-void
lr:0x20c951 = return-void
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatTextHelperV17.applyCompoundDrawablesTints()
lr:0x2064ad = invoke-super {v3},kind@4cbb
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatTextHelper.applyCompoundDrawablesTints()
lr:0x2046e7 = iget-object v0,v3,field@32e5
lr:0x206943 = if-nez v0,+0x000e
lr:0x2046e7 = iget-object v0,v3,field@32e7
lr:0x206943 = if-nez v0,+0x000a
lr:0x2046e7 = iget-object v0,v3,field@32e6
lr:0x206943 = if-nez v0,+0x0006
lr:0x2046e7 = iget-object v0,v3,field@32e4
lr:0x20466d = if-eqz v0,0x0028
lr:0x20c951 = return-void
lr:0x2046e7 = iget-object v0,v3,field@32ec
lr:0x206943 = if-nez v0,+0x0006
lr:0x2046e7 = iget-object v0,v3,field@32eb
lr:0x20466d = if-eqz v0,0x0018
lr:0x20c951 = return-void
lr:0x2046e7 = iget-object v0,v2,field@818a
lr:0x204c49 = invoke-virtual {v0,v1},kind@61b5
lr:0x2046e7 = iget-object v0,v2,field@818b
lr:0x204c49 = invoke-virtual {v0,v1},kind@61b5
lr:0x2046e7 = iget-object v0,v2,field@8189
lr:0x204c49 = invoke-virtual {v0,v1},kind@61b5
lr:0x205ccf = const/4 v0,#1
lr:0x204c49 = invoke-virtual {v3,v0},kind@5dab
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatImageView.drawableStateChanged()
lr:0x2064ad = invoke-super {v1},kind@614c
lr:0x2046e7 = iget-object v0,v1,field@32ae
lr:0x20466d = if-eqz v0,+0x0005
lr:0x204c49 = invoke-virtual {v0},kind@4b5b = void android.support.v7.widget.AppCompatBackgroundHelper.applySupportBackgroundTint()
lr:0x2046e7 = iget-object v0,v1,field@32af
lr:0x20466d = if-eqz v0,+0x0005
lr:0x204c49 = invoke-virtual {v0},kind@4bef
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatImageHelper.applySupportImageTint()
lr:0x2046e7 = iget-object v0,v3,field@32ad
lr:0x204c49 = invoke-virtual {v0},kind@6150
lr:0x206c21 = move-result-object v0
lr:0x20466d = if-eqz v0,0x0005
lr:0x203f87 = invoke-static {v0}, kind@4e6e
method start : >>>>>>>>>>>void android.support.v7.widget.DrawableUtils.fixDrawable(android.graphics.drawable.Drawable)
lr:0x203f09 = sget v0, field@0467
lr:0x204023 = const/16 v1, 0x0015
lr:0x204301 = if-ne v0,v1,0x0015
lr:0x20c951 = return-void
lr:0x20466d = if-eqz v0,0x0022
lr:0x206729 = invoke-direct {v3}, kind@4bf8
method start : >>>>>>>>>>>boolean android.support.v7.widget.AppCompatImageHelper.shouldApplyFrameworkTintUsingColorFilter()
lr:0x203f09 = sget v0, field@0467
lr:0x205ccf = const/4 v1,#1
lr:0x205ccf = const/4 v2,#0
lr:0x204023 = const/16 v3, 0x0015
lr:0x204b7b = if-le v0,v3,0x0009
lr:0x2046e7 = iget-object v0,v4,field@32ab
lr:0x20466d = if-eqz v0,0x0003
lr:0x205ccf = const/4 v1,#0
lr:0x20c9f1 = return v1
lr:0x2051d5 = move-result v1
lr:0x20466d = if-eqz v1,0x0009
lr:0x2046e7 = iget-object v1,v3,field@32aa
lr:0x20466d = if-eqz v1,0x000c
lr:0x2046e7 = iget-object v1,v3,field@32ab
lr:0x20466d = if-eqz v1,0x0003
lr:0x20c951 = return-void
lr:0x20c951 = return-void
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatTextHelperV17.applyCompoundDrawablesTints()
lr:0x2064ad = invoke-super {v3},kind@4cbb
method start : >>>>>>>>>>>void android.support.v7.widget.AppCompatTextHelper.applyCompoundDrawablesTints()
lr:0x2046e7 = iget-object v0,v3,field@32e5
lr:0x206943 = if-nez v0,+0x000e
lr:0x2046e7 = iget-object v0,v3,field@32e7
lr:0x206943 = if-nez v0,+0x000a
lr:0x2046e7 = iget-object v0,v3,field@32e6
lr:0x206943 = if-nez v0,+0x0006
lr:0x2046e7 = iget-object v0,v3,field@32e4
lr:0x20466d = if-eqz v0,0x0028
lr:0x20c951 = return-void
lr:0x2046e7 = iget-object v0,v3,field@32ec
lr:0x206943 = if-nez v0,+0x0006
lr:0x2046e7 = iget-object v0,v3,field@32eb
lr:0x20466d = if-eqz v0,0x0018
lr:0x20c951 = return-void
lr:0x20c951 = return-void
method end : >>>>>>>>>>>void com.xgtl.aggregate.activities.MainActivity.a(android.view.View)
cat test.apk.split1 test.apk.split2 test.apk.split3 > test.apk
看雪ID:飞翔的猫咪
https://bbs.pediy.com/user-home-607812.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!